package betAndWin.application.thread;


import betAndWin.application.GameControl;
import betAndWin.gui.HorseComponent;


public class HorseThread extends Thread {

	private static int lastAssignedId = 0;

	private GameControl gameControl;
	private int id;
	private double quota;
	private int priority;

	private HorseComponent horseComponent;
	private int position;

	public HorseThread(double pQuota, GameControl pGameControl, HorseComponent pHorseComp) {
		this.gameControl = pGameControl;
		this.id = lastAssignedId++;
		this.setName("Cavallo-" + this.id);
		this.quota = pQuota;
		this.priority = pGameControl.createPrio(quota);
		this.horseComponent = pHorseComp;
	}

	public HorseComponent getComponent() {
		return this.horseComponent;
	}

	public synchronized int getPosition() {
		return this.position;
	}
	
	public double getQuota() {
		return this.quota;
	}
	
	public int getHorseId() {
		return this.id;
	}

	public void run() {
		Thread prioThread = new PriorityThread(this);
		waitStartEvent();
		if (isInterrupted()) {
			prioThread.interrupt();
			return;
		}
		prioThread.start();
		horseComponent.setImageObserver(horseComponent);

		while (this.position < GameControl.CORSIA_LENGTH) {
			try {
				synchronized (prioThread) {
					Thread.sleep(this.priority);
				}
			} catch (InterruptedException e) {
				prioThread.interrupt();
				return;
			}

			// inizio: meccanismo per evitare di disegnare ogni volta TUTTA l'area del panel, risultato: GRANDE risparmio di risorse
			int prevX = horseComponent.getActualX();
			int prevY = horseComponent.getActualY();
			int imgWidth = horseComponent.getImage().getWidth(null);
			int imgHeight = horseComponent.getImage().getHeight(null);
			synchronized (this) {
				this.position++;
			}
			horseComponent.repaint(prevX, prevY, imgWidth, imgHeight);			// primo repaint per ridisegnare la zona precedente, in modo da eliminare del tutto l'immagine vecchia
			horseComponent.repaint(this.position, prevY, imgWidth, imgHeight);	// secondo repaint per disegnare il resto dello spostamento
			// fine: meccanismo per evitare...
		}
		prioThread.interrupt();		// fermo PriorityThread
		gameControl.updateClassification(this.id);
		System.out.println(getName() + ": finished");
	}

	public void waitStartEvent() {
		try {
			synchronized(gameControl) {
				gameControl.wait();
			}
		} catch (InterruptedException e) {
			interrupt();	// setto di nuovo il flag interrupt() a true cosi da poter fermare il thread in seguito
		}
	}

	public void updatePriority() {
		this.priority = this.gameControl.createPrio(this.quota);
	}
	
	public static void resetIdCounter() {
		lastAssignedId = 0;
	}
}
